summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAriya Hidayat <ariya.hidayat@nokia.com>2008-09-10 17:43:17 +0000
committerDavid Boddie <dboddie@trolltech.com>2008-09-10 17:43:17 +0000
commit9269160fdc7a9d08cce5b380868b1a83734b78bb (patch)
tree1f8b200cefb5ae389a0e563de5ecebf94a569465
parent5a60ad83c5cea7d74a28005e64bf9f821959f25d (diff)
Add image tinting example.
-rw-r--r--imagetint/berry.jpgbin0 -> 501881 bytes
-rw-r--r--imagetint/imagetint.cpp186
-rw-r--r--imagetint/imagetint.pro5
-rw-r--r--imagetint/imagetint.qrc5
-rw-r--r--imagetint/parameters.ui393
5 files changed, 589 insertions, 0 deletions
diff --git a/imagetint/berry.jpg b/imagetint/berry.jpg
new file mode 100644
index 0000000..fcc5034
--- /dev/null
+++ b/imagetint/berry.jpg
Binary files differ
diff --git a/imagetint/imagetint.cpp b/imagetint/imagetint.cpp
new file mode 100644
index 0000000..c9170d7
--- /dev/null
+++ b/imagetint/imagetint.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the Graphics Dojo project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "ui_parameters.h"
+
+class ImageTint: public QWidget
+{
+public:
+ ImageTint();
+ void loadImage(const QString &file);
+ void loadImage(const QImage &image);
+
+protected:
+ void dragEnterEvent(QDragEnterEvent*);
+ void dropEvent(QDropEvent *event);
+ void paintEvent(QPaintEvent*);
+
+private:
+ QString m_fileName;
+ QImage m_image;
+ Ui::ParametersForm parameters;
+};
+
+ImageTint::ImageTint()
+{
+ setAcceptDrops(true);
+
+ setAttribute(Qt::WA_StaticContents, true);
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+
+ QWidget* toolWidget = new QWidget(this);
+ toolWidget->setWindowFlags(Qt::Tool | Qt::WindowTitleHint);
+ parameters.setupUi(toolWidget);
+ toolWidget->show();
+ toolWidget->adjustSize();
+
+ connect(parameters.grayscaleButton, SIGNAL(toggled(bool)), this, SLOT(update()));
+ connect(parameters.tintButton, SIGNAL(toggled(bool)), this, SLOT(update()));
+ connect(parameters.redSlider, SIGNAL(valueChanged(int)), this, SLOT(update()));
+ connect(parameters.greenSlider, SIGNAL(valueChanged(int)), this, SLOT(update()));
+ connect(parameters.blueSlider, SIGNAL(valueChanged(int)), this, SLOT(update()));
+ connect(parameters.compositionModeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(update()));
+
+ parameters.redSlider->setValue(0);
+ parameters.greenSlider->setValue(0);
+ parameters.blueSlider->setValue(96);
+}
+
+void ImageTint::loadImage(const QImage &image)
+{
+ m_image = image;
+ if (m_image.isNull()) {
+ setFixedSize(512, 256);
+ setWindowTitle(QString("Can not load %1").arg(m_fileName));
+ } else {
+ QString title = "Image Tint ";
+ if ((m_image.width() > 1024) || (m_image.height() > 800)) {
+ qDebug() << "Image is too large. Rescaling....";
+ int w = m_image.width();
+ m_image = m_image.scaled(640, 480, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ title += QString("[Zoom %1%] ").arg(m_image.width() * 100 / w);
+ }
+ setWindowTitle(QString("%1: %2 (%3 x %4)").arg(title).arg(m_fileName).
+ arg(m_image.width()).arg(m_image.height()));
+ setFixedSize(m_image.width(), m_image.height());
+ }
+ update();
+}
+
+void ImageTint::loadImage(const QString &fileName)
+{
+ m_fileName = QFileInfo(fileName).fileName();
+ loadImage(QImage(fileName));
+}
+
+void ImageTint::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasFormat("text/uri-list"))
+ event->acceptProposedAction();
+}
+
+void ImageTint::dropEvent(QDropEvent *event)
+{
+ QList<QUrl> urls = event->mimeData()->urls();
+ if (urls.count()) {
+ QString fname = urls[0].toLocalFile();
+ if (event->mimeData()->hasImage()) {
+ QImage img = qvariant_cast<QImage>(event->mimeData()->imageData());
+ m_fileName = QFileInfo(fname).fileName();
+ loadImage(img);
+ } else
+ loadImage(fname);
+ event->acceptProposedAction();
+ }
+}
+
+// Convert an image to grayscale and return it as a new image
+QImage grayscaled(const QImage &image)
+{
+ QImage img = image;
+ int pixels = img.width() * img.height();
+ unsigned int *data = (unsigned int *)img.bits();
+ for (int i = 0; i < pixels; ++i) {
+ int val = qGray(data[i]);
+ data[i] = qRgba(val, val, val, qAlpha(data[i]));
+ }
+ return img;
+}
+
+// Tint an image with the specified color and return it as a new image
+QImage tinted(const QImage &image, const QColor &color, QPainter::CompositionMode mode = QPainter::CompositionMode_Screen)
+{
+ QImage resultImage(image.size(), QImage::Format_ARGB32_Premultiplied);
+ QPainter painter(&resultImage);
+ painter.drawImage(0, 0, grayscaled(image));
+ painter.setCompositionMode(mode);
+ painter.fillRect(resultImage.rect(), color);
+ painter.end();
+ resultImage.setAlphaChannel(image.alphaChannel());
+
+ return resultImage;
+}
+
+void ImageTint::paintEvent(QPaintEvent*)
+{
+ QPainter painter(this);
+
+ if (parameters.noEffectButton->isChecked())
+ painter.drawImage(0, 0, m_image);
+
+ if (parameters.grayscaleButton->isChecked())
+ painter.drawImage(0, 0, grayscaled(m_image));
+
+ if (parameters.tintButton->isChecked()) {
+ QColor tintColor;
+ tintColor.setRed(parameters.redSlider->value());
+ tintColor.setGreen(parameters.greenSlider->value());
+ tintColor.setBlue(parameters.blueSlider->value());
+
+ QPainter::CompositionMode table[] = {
+ QPainter::CompositionMode_Screen,
+ QPainter::CompositionMode_Overlay,
+ QPainter::CompositionMode_Multiply
+ };
+ QPainter::CompositionMode mode = table[parameters.compositionModeBox->currentIndex()];
+
+ painter.drawImage(0, 0, tinted(m_image, tintColor, mode));
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ ImageTint widget;
+ widget.show();
+ if (argc > 1)
+ widget.loadImage(argv[1]);
+ else
+ widget.loadImage(":/berry.jpg");
+
+ return app.exec();
+}
diff --git a/imagetint/imagetint.pro b/imagetint/imagetint.pro
new file mode 100644
index 0000000..0a45389
--- /dev/null
+++ b/imagetint/imagetint.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+TARGET = imagetint
+SOURCES = imagetint.cpp
+RESOURCES = imagetint.qrc
+FORMS = parameters.ui
diff --git a/imagetint/imagetint.qrc b/imagetint/imagetint.qrc
new file mode 100644
index 0000000..b75bd43
--- /dev/null
+++ b/imagetint/imagetint.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource>
+ <file>berry.jpg</file>
+ </qresource>
+</RCC>
diff --git a/imagetint/parameters.ui b/imagetint/parameters.ui
new file mode 100644
index 0000000..1ac08d9
--- /dev/null
+++ b/imagetint/parameters.ui
@@ -0,0 +1,393 @@
+<ui version="4.0" >
+ <class>ParametersForm</class>
+ <widget class="QWidget" name="ParametersForm" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>290</width>
+ <height>204</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Parameters</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QWidget" native="1" name="widget" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="noEffectButton" >
+ <property name="text" >
+ <string>No Effect</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="grayscaleButton" >
+ <property name="text" >
+ <string>Grayscale</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="tintButton" >
+ <property name="text" >
+ <string>Tint</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" native="1" name="optionsWidget" >
+ <layout class="QGridLayout" name="gridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Red</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSlider" name="redSlider" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ <property name="value" >
+ <number>0</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QSpinBox" name="redSpinBox" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Green</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSlider" name="greenSlider" >
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ <property name="value" >
+ <number>0</number>
+ </property>
+ <property name="sliderPosition" >
+ <number>0</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QSpinBox" name="greenSpinBox" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_7" >
+ <property name="text" >
+ <string>Blue</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QSlider" name="blueSlider" >
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ <property name="value" >
+ <number>99</number>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" >
+ <widget class="QSpinBox" name="blueSpinBox" >
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" native="1" name="widget_2" >
+ <layout class="QFormLayout" name="formLayout" >
+ <property name="margin" >
+ <number>1</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Composition Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QComboBox" name="compositionModeBox" >
+ <item>
+ <property name="text" >
+ <string>Screen</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Overlay</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Multiply</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>redSlider</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>redSpinBox</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>214</x>
+ <y>100</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>271</x>
+ <y>103</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>greenSlider</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>greenSpinBox</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>214</x>
+ <y>128</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>271</x>
+ <y>131</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>blueSlider</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>blueSpinBox</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>214</x>
+ <y>156</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>271</x>
+ <y>159</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>redSpinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>redSlider</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>271</x>
+ <y>103</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>214</x>
+ <y>100</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>greenSpinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>greenSlider</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>271</x>
+ <y>131</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>214</x>
+ <y>128</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>blueSpinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>blueSlider</receiver>
+ <slot>setValue(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>271</x>
+ <y>159</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>214</x>
+ <y>156</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>tintButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>redSlider</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>40</x>
+ <y>65</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>62</x>
+ <y>89</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>tintButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>greenSlider</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>58</x>
+ <y>65</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>63</x>
+ <y>120</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>tintButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>blueSlider</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>80</x>
+ <y>65</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>93</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>tintButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>redSpinBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>239</x>
+ <y>64</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>246</x>
+ <y>89</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>tintButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>greenSpinBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>262</x>
+ <y>65</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>263</x>
+ <y>118</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>tintButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>blueSpinBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>230</x>
+ <y>64</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>251</x>
+ <y>151</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>